package com.qf.day06.customfactory.utils;

import com.qf.day06.customfactory.service.UserService;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class MyFactory {

    private String configFilePath;//配置文件在classpath下的文件名
    private Properties properties = new Properties();//该实例属性用于保存解析后的配置文件中的内容
    private Map<String, Object> cache = new HashMap<>();//该工厂的对象缓存

    public MyFactory(String configFilePath) {
        this.configFilePath = configFilePath;
        //配置文件--->InputStream
        InputStream in = this.getClass().getClassLoader().getResourceAsStream(configFilePath);
        try {
            //把输入流中的内容转换成properties对象中的信息，完成properties的初始化
            properties.load(in);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public MyFactory() {
        //调用单参构造函数
        this("beans.properties");
    }

    /**
     * 获得对象的方法
     *
     * @param beanName 是对象的标识
     * @return 返回一个可用的对象
     */
    public Object getBean(String beanName) {
        //先检查一下工厂的缓存中是否含有该标识对应的对象，如果有，则直接返回
        Object obj = cache.get(beanName);
        if (obj != null) {
            return obj;
        }
        //根据beanName获取所需bean的类的全限定名
        String clazzName = properties.getProperty(beanName);
        //根据类的全限定名创建对象
        obj = createObject(clazzName);
        //存入缓存区
        cache.put(beanName, obj);
        System.out.println("存缓存了");
        //返回对象
        return obj;
    }

    /**
     * 反射创建对象
     *
     * @param clazzName 对象的全限定名
     * @return
     */
    private Object createObject(String clazzName) {
        Object obj = null;
        try {
            //加载Class
            Class<?> clazz = Class.forName(clazzName);
            //反射创建对象并返回
            obj = clazz.newInstance();
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            throw new RuntimeException(e);
        } finally {
            return obj;
        }
    }

    public static void main(String[] args) {
        //创建工厂对象
        MyFactory myFactory = new MyFactory();
        //使用工厂对象，获取所需的业务对象
        UserService userService1 = (UserService) myFactory.getBean("userService");
        UserService userService2 = (UserService) myFactory.getBean("userService");
        //使用业务对象
        System.out.println(userService1.getUser(100));
        System.out.println(userService2.getUser(100));
    }
}
